package com.haowu.customer.dubbo;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.haowu.common.core.constant.UserConstants;
import com.haowu.common.core.enums.AuthType;
import com.haowu.common.core.enums.UserStatus;
import com.haowu.common.core.enums.UserType;
import com.haowu.common.core.exception.user.UserException;
import com.haowu.common.core.utils.BeanCopyUtils;
import com.haowu.customer.api.RemoteCustomerService;
import com.haowu.customer.api.domain.HwAppCustomer;
import com.haowu.customer.api.domain.HwAppSocialAuth;
import com.haowu.customer.api.model.CustomerInfo;
import com.haowu.customer.api.model.LoginCustomer;
import com.haowu.customer.api.model.XcxLoginCustomer;
import com.haowu.customer.mapper.HwAppCustomerMapper;
import com.haowu.customer.mapper.HwAppSocialAuthMapper;
import com.haowu.customer.service.IHwAppCustomerService;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * app会员登录
 *
 * @author Lion Li
 */
@RequiredArgsConstructor
@Service
@DubboService
public class RemoteCustomerLoginServiceImpl implements RemoteCustomerService {
    private final IHwAppCustomerService customerService;
    private final HwAppCustomerMapper customerMapper;
    private final HwAppSocialAuthMapper authMapper;

    /**
     * 根据账号名查询顾客信息
     * @param account 顾客账号
     * @return 顾客登录封装对象
     * @throws UserException 用户信息异常类
     */
    @Override
    public LoginCustomer getCustomerInfo(String account) throws UserException {
        HwAppCustomer cusInfo = customerMapper.selectOne(new LambdaQueryWrapper<HwAppCustomer>()
            .select(HwAppCustomer::getUserName, HwAppCustomer::getStatus)
            .eq(HwAppCustomer::getUserName, account));
        if (ObjectUtil.isNull(cusInfo)) {
            throw new UserException("user.not.exists", account);
        }
        if (UserStatus.DISABLE.getCode().equals(cusInfo.getStatus())) {
            throw new UserException("user.blocked", account);
        }
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        return buildLoginUser(customerMapper.selectUserByAccount(account));
    }

    /**
     * 根据手机号查询顾客信息
     * @param phonenumber 手机号
     * @return 顾客登录封装对象
     * @throws UserException 用户信息异常类
     */
    @Override
    public LoginCustomer getCustomerInfoByPhonenumber(String phonenumber) throws UserException {
        HwAppCustomer cusInfo = customerMapper.selectOne(new LambdaQueryWrapper<HwAppCustomer>()
            .select(HwAppCustomer::getUserPhone, HwAppCustomer::getStatus)
            .eq(HwAppCustomer::getUserPhone, phonenumber));
        if (ObjectUtil.isNull(cusInfo)) {
            throw new UserException("user.not.exists", phonenumber);
        }
        if (UserStatus.DISABLE.getCode().equals(cusInfo.getStatus())) {
            throw new UserException("user.blocked", phonenumber);
        }
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        return buildLoginUser(customerMapper.selectUserByPhonenumber(phonenumber));
    }

    /**
     * 根据小程序openid查询顾客信息
     * @param openid 微信小程序授权openid
     * @return 顾客小程序登录封装对象
     * @throws UserException 用户信息异常类
     */
    @Override
    public XcxLoginCustomer getCustomerInfoByOpenid(String openid, String unionid, String phonenumber) throws UserException {
        //微信强制绑定手机号,根据小程序可以获取到手机号就根据手机号去判断用户是否存在
        HwAppCustomer cusInfo = customerMapper.selectOne(new LambdaQueryWrapper<HwAppCustomer>()
            .select(HwAppCustomer::getUserPhone, HwAppCustomer::getStatus)
            .eq(HwAppCustomer::getUserPhone, phonenumber));
        if(ObjectUtil.isNotNull(cusInfo)){
            if (ObjectUtil.isNull(cusInfo)) {
                throw new UserException("user.not.exists", phonenumber);
            }
            if (UserStatus.DISABLE.getCode().equals(cusInfo.getStatus())) {
                throw new UserException("user.blocked", phonenumber);
            }
            //根据账号信息中的手机号反查出用户信息并构造xcxloginUser
            CustomerInfo loginUser = customerMapper.selectUserByPhonenumber(cusInfo.getUserPhone());
            XcxLoginCustomer xcxLoginCustomer = (XcxLoginCustomer) buildLoginUser(loginUser);
            xcxLoginCustomer.setOpenId(openid);
            //判断是否需要插入或更新social_auth表
            HwAppSocialAuth socialAuth = authMapper.selectOne(new LambdaQueryWrapper<HwAppSocialAuth>()
                .eq(HwAppSocialAuth::getAuthIdentification, openid)
                .eq(HwAppSocialAuth::getAuthType, AuthType.WX_XCX.getAuthType()));
            if(ObjectUtil.isNotNull(socialAuth)){
                socialAuth.setAuthType(AuthType.WX_XCX.getAuthType());
                socialAuth.setAuthIdentification(openid);
                Optional.ofNullable(unionid).ifPresent(socialAuth::setUnionId);
            }else{
                socialAuth = new HwAppSocialAuth();
                socialAuth.setAuthType(AuthType.WX_XCX.getAuthType());
                socialAuth.setAuthIdentification(openid);
                socialAuth.setIsDelete(0);
                socialAuth.setUid(cusInfo.getId());
                Optional.ofNullable(unionid).ifPresent(socialAuth::setUnionId);
            }
            authMapper.insertOrUpdate(socialAuth);
            return xcxLoginCustomer;
        }else{
            //根据手机号未查询到用户,则需要新创建用户,给定一个默认密码?
            String password = "123456";
            HwAppCustomer account = new HwAppCustomer();
            account.setUserName(phonenumber);
            account.setPassword(BCrypt.hashpw(password));
            boolean regFlag = registerCustomer(account);
            if (!regFlag) {
                throw new UserException("user.register.error");
            }else{
                CustomerInfo registerCus = customerMapper.selectUserByPhonenumber(cusInfo.getUserPhone());
                XcxLoginCustomer xcxLoginCustomer = (XcxLoginCustomer) buildLoginUser(registerCus);
                xcxLoginCustomer.setOpenId(openid);
                //注册成功,需要插入一条小程序授权记录到social_auth
                HwAppSocialAuth socialAuth = new HwAppSocialAuth();
                socialAuth.setAuthType(AuthType.WX_XCX.getAuthType());
                socialAuth.setAuthIdentification(openid);
                socialAuth.setIsDelete(0);
                socialAuth.setUid(registerCus.getId());
                Optional.ofNullable(unionid).ifPresent(socialAuth::setUnionId);
                authMapper.insert(socialAuth);
                return xcxLoginCustomer;
            }
        }

/*        //第三方授权表查询是否存在openid匹配的小程序账号记录
        HwAppSocialAuth socialAuth = authMapper.selectOne(new LambdaQueryWrapper<HwAppSocialAuth>()
            .select(HwAppSocialAuth::getUid, HwAppSocialAuth::getIsDelete)
            .eq(HwAppSocialAuth::getAuthIdentification, openid)
            .eq(HwAppSocialAuth::getAuthType, AuthType.WX_XCX.getAuthType()));
        if(ObjectUtil.isNotNull(socialAuth)){
            //根据小程序openid直接查询到第三方授权表,则可以直接查询出用户信息并登录
            //如果存在授权记录，根据uid查询该用户的账号信息
            HwAppCustomer cusInfo = customerMapper.selectOne(new LambdaQueryWrapper<HwAppCustomer>()
                .select(HwAppCustomer::getUserPhone, HwAppCustomer::getStatus)
                .eq(HwAppCustomer::getId, socialAuth.getUid()));
            if (ObjectUtil.isNull(cusInfo)) {
                throw new UserException("user.not.exists");
            }
            if (UserStatus.DISABLE.getCode().equals(cusInfo.getStatus())) {
                throw new UserException("user.blocked");
            }
            //根据账号信息中的手机号反查出用户信息并构造xcxloginUser
            CustomerInfo loginUser = customerMapper.selectUserByPhonenumber(cusInfo.getUserPhone());
            XcxLoginCustomer xcxLoginCustomer = (XcxLoginCustomer) buildLoginUser(loginUser);
            xcxLoginCustomer.setOpenId(openid);
            //第三方授权表更新unionid
            if(StringUtils.isNotEmpty(unionid)){
                socialAuth.setUnionId(unionid);
                authMapper.updateById(socialAuth);
            }
            return xcxLoginCustomer;
        }else{
            //如果根据openid未查询到结果,则判断本次unionid传参是否为空,为空说明微信小程序是首次登录
            //此时需要直接插入一条social_auth记录,并根据手机号判断是否需要创建新用户
            if(StringUtils.isEmpty(unionid)){

            }else{
                //如果不为空,则根据unionid查询social_auth,如果查询到则说明微信客户端授权登录过
                //第三方授权表查询是否存在unionid匹配的微信授权记录
                HwAppSocialAuth unionAuth = authMapper.selectOne(new LambdaQueryWrapper<HwAppSocialAuth>()
                    .select(HwAppSocialAuth::getUnionId, HwAppSocialAuth::getIsDelete)
                    .eq(HwAppSocialAuth::getUnionId, unionid));
            }
            return null;
        }*/
    }

    /**
     * 用户注册
     * @param appCustomer 用户信息
     * @return 是否注册成功
     */
    @Override
    public Boolean registerCustomer(HwAppCustomer appCustomer) {
        String account = appCustomer.getUserName();
        if (UserConstants.NOT_UNIQUE.equals(customerService.checkAccountUnique(appCustomer))) {
            throw new UserException("user.register.save.error", account);
        }
        return customerService.registerUser(appCustomer);
    }

    /**
     * 构建登录用户
     */
    private LoginCustomer buildLoginUser(CustomerInfo customerInfo) {
        LoginCustomer loginCustomer = BeanCopyUtils.copy(customerInfo, LoginCustomer.class);
        loginCustomer.setUserType(UserType.CUS_USER.getUserType());
        return loginCustomer;
    }

}
